import logging
import re

from QQLoginTool.QQtool import OAuthQQ
from django import http
from django.conf import settings
from django.contrib.auth import login
from django.shortcuts import render, redirect
from django.views import View
from django_redis import get_redis_connection

from meiduo_mall.utils.response_code import RETCODE
from oauth.models import OAuthQQUser
from users.models import User
from .utils import generate_access_token, check_access_token

# Create your views here.

logger = logging.getLogger('django')


class QQAuthUserView(View):
    """扫码登陆的回调处理"""

    def get(self, request):
        """处理QQ登陆回调的业务逻辑"""
        # 获取code
        code = request.GET.get('code')

        # 创建对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)

        try:
            # 根据code 获取QQ的access_token
            access_token = oauth.get_access_token(code)

            # 根据access_token 获取QQ的openid
            openid = oauth.get_open_id(access_token)

        except Exception as e:
            logger.error(e)
            return http.HttpResponseServerError('OAuth2.0失败')

        try:
            # 根据openid判断QQ用户是否绑定过用户
            oauth_user = OAuthQQUser.objects.get(openid=openid)

        except OAuthQQUser.DoseNetExist:
            # 用户从未绑定过商城系统
            access_token_openid = generate_access_token(openid)
            context = {'access_token_openid': access_token_openid}
            return render(request, 'oauth_callback.html', context)

        else:
            # 用户已绑定系统
            # 状态保存
            login(request, oauth_user.user)

            # 重定向到首页
            next = request.GET.get('state')
            response = redirect(next)

            # 将用户写入cookie中
            response.set_cookie('username', oauth_user.user, max_age=3600 * 24 * 15)

            # 重定向到首页
            return response

    def post(self, request):
        """实现绑定用户逻辑"""
        # 接收参数
        mobile = request.POST.get('mobile')
        pwd = request.POST.get('password')
        sms_code_client = request.POST.get('sms_code')
        access_token = request.POST.get('access_token')

        # 校验参数
        if not all([mobile, pwd, sms_code_client]):
            return http.HttpResponseForbidden('缺少必传参数')

        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入正确的手机号码')

        # 判断密码是否合格
        if not re.match(r'^[0-9A-Za-z]{8,20}$', pwd):
            return http.HttpResponseForbidden('请输入8-20位的密码')

        # 判断短信验证码是否一致
        redis_conn = get_redis_connection('verify_code')
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        if sms_code_server is None:
            return render(request, 'oauth_callback.html', {'sms_code_errmsg': '无效的短信验证码'})
        if sms_code_client != sms_code_server.decode():
            return render(request, 'oauth_callback.html', {'sms_code_errmsg': '输入短信验证码有误'})

        # p判断openid是否有效
        openid = check_access_token(access_token)
        if not openid:
            return render(request, 'oauth_callback.html', {'openid_errmsg': 'openid已失效'})

        # 实现主体业务逻辑
        # 判断手机号是否存在
        try:
            user = User.objects.get(mobile=mobile)

        except User.DoesNotExist:
            # 用户不存在，创建新用户
            user = User.objects.create_user(username=mobile, password=pwd, mobile=mobile)

        else:
            # 用户存在，校验密码是否正确
            if not user.check_password(pwd):
                return render(request, 'oauth_callback.html', {'account_errmsg': '用户名或密码错误'})

        # 将新建/已存 用户绑定到openid
        # oauth_qq_user = OAuthQQUser(openid=openid, user=user)
        # oauth_qq_user.save()
        try:
            oauth_qq_user = OAuthQQUser.objects.create(openid=openid, user=user)
        except Exception as e:
            logger.error(e)
            return render(request, 'oauth_callback.html', {'qq_login_errmsg': 'QQ登录失败'})

        # 状态保存
        login(request, oauth_qq_user.user)

        # 重定向到首页
        next = request.GET.get('state')
        response = redirect(next)

        # cookie写入到用户名中
        response.set_cookie('username', oauth_qq_user.username, max_age=3600 * 24 * 15)

        # 返回响应
        return response


class QQAuthURLView(View):
    """提供QQ登陆扫码页面"""

    def get(self, request):
        # 接收参数
        next = request.GET.get('next')
        # 创建对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI, state=next)
        # 创建扫码登陆页面
        login_url = oauth.get_qq_url()
        # 返回响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})
